<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .map {
            position: relative;
            margin: 0 auto;
        }

        .snack {
            position: absolute;
        }

        .food {
            position: absolute;
        }
    </style>
</head>
<body>
<script>
    /*
     * 创建函数对象
     * */
    //1.创建地图实例
    var map, snack, food;
    function Map() {
        this.width = 900;
        this.height = 600;
        this.bgColor = "#000";
        this.speed = 800;
        this._map = null;//存储dom
        this.timer = null;
        this.resetTimer = function () {
            var that = this;
            if (that.timer) {
                clearInterval(that.timer);
            }
            that.timer = setInterval('snack.move()', that.speed);
        };
        this.createMap = function () {
            if (this._map == null) {
                this._map = document.createElement("div");
                this._map.style.width = this.width + "px";
                this._map.style.height = this.height + "px";
                this._map.style.backgroundColor = this.bgColor;
                this._map.classList.add("map");
                document.body.appendChild(this._map);
            }
        }
    }

    //2.创建蛇的实例
    function Snack() {
        this.w = 30;
        this.h = 30;
        this._snack = [['red', null, 3, 1], ['#fff', null, 2, 1], ['#fff', null, 1, 1]];
        this.direct = "right";
        this.createSnack = function () {
            for (var i = 0; i < this._snack.length; i++) {
                if (this._snack[i][1] == null) {
                    //创建元素
                    this._snack[i][1] = document.createElement("div");
                    this._snack[i][1].style.width = this.w + "px";
                    this._snack[i][1].style.height = this.h + "px";
                    this._snack[i][1].style.backgroundColor = this._snack[i][0];
                    this._snack[i][1].classList.add("snack");
                    //将创建的蛇添加到地图
                    map._map.appendChild(this._snack[i][1]);
                }
                //直接修改坐标
                this._snack[i][1].style.left = this.w * this._snack[i][2] + "px";
                this._snack[i][1].style.top = this.h * this._snack[i][3] + "px";

            }
        };
        this.move = function () {
            //从后到前  获取前面一节的坐标
            var len = this._snack.length - 1;
            for (var i = len; i > 0; i--) {
                this._snack[i][2] = this._snack[i - 1][2];
                this._snack[i][3] = this._snack[i - 1][3];
            }
            //蛇头根据方向变
            switch (this.direct) {
                case "left":
                    this._snack[0][2] -= 1;
                    break;
                case "right":
                    this._snack[0][2] += 1;
                    break;
                case "up":
                    this._snack[0][3] -= 1;
                    break;
                case "down":
                    this._snack[0][3] += 1;
                    break;
            }

            //蛇头是否吃到食物
            this.iseatfood();
            this.goqiang();
            this.createSnack();

        };
        this.iseatfood = function () {
            if (this._snack[0][2] == food.x && this._snack[0][3] == food.y) {
                //蛇增加一节 食物重新随机位置
                var len = this._snack.length - 1;
                var x = this._snack[len][2];
                var y = this._snack[len][3];
                this._snack.push(['#fff', null, x, y]);
                food.createFood();
            }
        };
        this.goqiang = function () {
            //移动之后  去检测  是否可以穿墙
            //只管蛇头
            if (this._snack[0][2] > 29) {
                this._snack[0][2] = 0;
            }
            if (this._snack[0][2] < 0) {
                this._snack[0][2] = 29;
            }
            if (this._snack[0][3] > 19) {
                this._snack[0][3] = 0;
            }
            if (this._snack[0][3] < 0) {
                this._snack[0][3] = 19;
            }
        }
    }

    //创建食物实例
    function Food() {
        this.w = 30;
        this.h = 30;
        this.fcolor = "pink";
        this.x;
        this.y;
        this._food = null;
        this.checkPos = function () {
            //检测食物坐标不能在蛇身上
            var iswhile = false;
            do {
                //随机坐标
                this.x = Math.floor(Math.random() * 30);
                this.y = Math.floor(Math.random() * 20);
                var ishas = false;
                for (var i = 0; i < snack._snack.length; i++) {
                    if (snack._snack[i][2] == this.x && snack._snack[i][3] == this.y) {
                        ishas = true;
                        break;
                    }
                }
                if (ishas) {
                    iswhile = true;
                }
                else {
                    iswhile = false;
                }

            }
            while (iswhile);
        };
        this.createFood = function () {
            //检测坐标
            this.checkPos();
            if (this._food == null) {
                this._food = document.createElement("div");
                this._food.style.width = this.w + "px";
                this._food.style.height = this.h + "px";
                this._food.style.backgroundColor = this.fcolor;
                this._food.classList.add("food");
                map._map.appendChild(this._food);
            }
            this._food.style.left = this.x * this.w + "px";
            this._food.style.top = this.y * this.h + "px";
        }
    }

    window.onload = function () {
        map = new Map();
        map.createMap();

        snack = new Snack();
        snack.createSnack();

        food = new Food();
        food.createFood();

        //设置计时
        map.resetTimer();

        //添加键盘事件
        document.body.onkeyup = function (e) {
            checkWay(e);

            if (keyCode) {
                keyCode = null;
                map.speed = 800;
                map.resetTimer();
                lianxu = false;
            }
        }
        //变量
        var keyCode = null;
        var lianxu = false;
        document.body.onkeydown = function (e) {
            var key = e.key;
            if (key == "ArrowLeft" || key == "ArrowRight" || key == "ArrowUp" || key == "ArrowDown") {
                if (keyCode == key && lianxu == false) {
                    lianxu = true;
                    checkWay(e);
                    map.speed = 50;
                    map.resetTimer();
                }
                keyCode = key;
            }
        }

        //检测方向方法
        function checkWay(e) {
            switch (e.key) {
                case "ArrowLeft":
                    if (snack.direct != 'right')
                        snack.direct = "left";
                    break;
                case "ArrowRight":
                    if (snack.direct != 'left')
                        snack.direct = "right";
                    break;
                case "ArrowUp":
                    if (snack.direct != 'down')
                        snack.direct = "up";
                    break;
                case "ArrowDown":
                    if (snack.direct != 'up')
                        snack.direct = "down";
                    break;
            }
        }
    }
</script>
</body>
</html>